package java基础知识;

import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.HashMap;

/**
 * @author coderFu
 * @create 2022/2/8
 * 注解， So easy
 */
 class AnnotationSoEasy {

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        // 获取使用注解的类对象
        Class<AnnotationUse> annotationUseClass = AnnotationUse.class;
        //通过类对象获取实例对象
        AnnotationUse annotationUse = annotationUseClass.newInstance();
        System.out.println("方法一：通过默认无惨构造创建实例对象"+annotationUse);
        Constructor<AnnotationUse> constructor1 = annotationUseClass.getConstructor();
        AnnotationUse annotationUse1 = constructor1.newInstance();
        System.out.println("方法二：通过构造方法创建"+annotationUse1);
        Constructor<?>[] constructors = annotationUseClass.getConstructors();
        System.out.println("构造方法的个数为"+constructors.length);
        for (Constructor constructor : constructors){
            System.out.println("构造方法的参数个数为"+constructor.getParameterCount());
            if (constructor.getParameterCount()>0){
                Parameter[] parameters = constructor.getParameters();
                System.out.println(Arrays.toString(parameters));
                HashMap<String, String> hashMap = new HashMap<>();
                for (Parameter parameter : parameters){
                    Class<?> type = parameter.getType();
                    String name1 = type.getName();
                    System.out.println(name1);
                    String name = parameter.getName();
                    System.out.println(name);
                    if (name1.contains("String")){
                        System.out.println("参数为"+name);
                        hashMap.put(name1,"付银磊");
                    }else if ("int".equals(name1)){
                        System.out.println("参数为"+name);
                        hashMap.put(name1,"23");
                    }
                }
                Object o = constructor.newInstance(hashMap.get(parameters[0].getType().getName()), Integer.parseInt(hashMap.get(parameters[1].getType().getName())));
                System.out.println(o);
            }
        }


        // 获取类中的构造方法
        Constructor<AnnotationUse> constructor = annotationUseClass.getConstructor();
        System.out.println("构造方法有:"+constructor.getName());
        System.out.println("===================");
        ClassInfo annotation = annotationUseClass.getAnnotation(ClassInfo.class);
        if (annotation != null){
            System.out.println("类上的注解值为"+annotation.value());
        }

        //获取属性上的注解
        Field[] declaredFields = annotationUseClass.getDeclaredFields();
        for (Field field : declaredFields){
            FieldInfo fieldAnnotation = field.getAnnotation(FieldInfo.class);
            if (fieldAnnotation != null){
                //注解要求的长度为
                int length = fieldAnnotation.length();
                System.out.println("注解要求的长度为:"+length);
                //注解的名称为
                String name = fieldAnnotation.value();
                System.out.println("注解的名称为"+name);
                String fieldName = field.getName();
                System.out.println(fieldName);
                Object fieldValue = field.get(annotationUse);
//                Object fieldValue2 = field.get(annotationUseClass);
//                System.out.println("通过类对象获取"+fieldValue2);
                System.out.println("属性的值为"+fieldValue);
                //判断是否满足长度要求
                if ((fieldValue.toString().length() == length)){
                    System.out.println("属性值的长度满足要求可以通过");
                }else {
                    System.out.println("属性值的长度不满足要求不可以通过");
                }
            }
        }

        Method[] methods = annotationUseClass.getMethods();
        for (Method method : methods){
            MethodInfo  methodAnnotation = method.getAnnotation(MethodInfo.class);
            if (methodAnnotation != null){
                System.out.println("方法上的注解为"+methodAnnotation.value());
                //调用一下方法
                System.out.println(method.invoke(annotationUse));
                //当方法是静态方法的时候，class类对象和实例对象都可以使用
                //当方法非静态方法的时候，需要实例对象才可以使用
//                System.out.println(method.invoke(annotationUseClass));
            }

        }


        // 关键字: @interface

        //四个源注解： 常用的两个 @Retention 生命周期  @Target 修饰目标的信息

        //使用注解的时候，被注解标注的成员（类成员+属性成员） 赋值是通过@Annotation（name = value）
        //实现


        //注解的分类： 内置注解： 是指java中内置的注解  @override @Deprecated @SuppressWarnings
        //源注解： Target   Retention （Source class Runtime） Document Inherited(表示是否能被子注解继承）
        //注解的生命周期：
           // Retention     SOURCE : 注解只被保留在源文件，当java文件编译成class文件的时候，注解被遗弃
        //                  CLASS : 注解被保留到class文件，但JCVM加载class文佳的时候被遗弃，这是默认的生命周期
        //                  RUNTIME: 注解不仅被保留到class文件中，jvm加载class文件之后，仍然存在，保存在class对象中，可以通过反射来获取
        // Target 表示注解使用的地方
                          //  Package : 包
                         //  Type 类，接口
                         //  FIELD  属性，方法
                        //   Method 方法
                        //   parameter 构造函数
                        //  ANNOTATION_TYPE 注解上使用的源注解

    }
}

@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.ANNOTATION_TYPE})
@interface MyInterface{
    ElementType[] value();
}
